package pers.chy.chyappointmentplatform.Filter;

import com.auth0.jwt.interfaces.Claim;
import com.google.gson.Gson;
import com.google.gson.reflect.TypeToken;
import lombok.extern.slf4j.Slf4j;
import org.apache.ibatis.jdbc.Null;
import pers.chy.chyappointmentplatform.Model.NoMapping.ReplyMsgDTO;
import pers.chy.chyappointmentplatform.Model.V_YgxxDTO;
import pers.chy.chyappointmentplatform.Utils.JwtUtil;

import javax.servlet.*;
import javax.servlet.annotation.WebFilter;
import javax.servlet.http.Cookie;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import java.io.IOException;
import java.util.List;
import java.util.Map;

/**
 * JWT过滤器，拦截请求
 */
@Slf4j
//@WebFilter(filterName = "JwtFilter", urlPatterns = "/secure/*")
//@WebFilter(filterName = "JwtFilter", urlPatterns = "/ViewController/*")
@WebFilter(filterName = "JwtFilter", urlPatterns = {
        "/ViewController/*",
        "/CallNumberController/*",
        "/LydjController/*",
        "/StatisticController/*"
})
public class JwtFilter implements Filter {
    @Override
    public void init(FilterConfig filterConfig) throws ServletException {
    }

    @Override
    public void doFilter(ServletRequest req, ServletResponse res, FilterChain chain) throws IOException, ServletException {
        final HttpServletRequest request = (HttpServletRequest) req;
        final HttpServletResponse response = (HttpServletResponse) res;


        //
        // 放行的URL
        //

        // 不拦截的页面
        String uri = ((HttpServletRequest) req).getRequestURI();
        if (uri.contains("/ViewController/Login")
                || uri.contains("/ViewController/Statistic_Yj_SqdTimePoint")
                || uri.contains("/ViewController/Statistic_Yj_WorkingTime_Ys")
                || uri.contains("/ViewController/Statistic_Yj_WorkingTime_Zt")) {
            chain.doFilter(request, response);
            return;
        }

        //
        // JWT验证
        //

        // 获取cookie中的token

        String token = null;
        Cookie[] cookies = request.getCookies();
        if (cookies != null) {
            // 遍历数组
            for (Cookie cookie : cookies) {
                if (cookie.getName().equals("token")) {
                    // 取出token
                    token = cookie.getValue();
                    break;
                }
            }
        }

        // 验证token
        try {
            // 验证有效性
            Map<String, Claim> userData = JwtUtil.verifyToken(token);

            // 验证是否有权限访问View视图
            if (uri.contains("ViewController")) {

                // 获取此用户拥有的角色权限列表
                List<Long> list = new Gson().fromJson(userData.get("RoleIdList").asString(), new TypeToken<List<Long>>() {
                }.getType());

                // 暂时写死：判断此用户是否有权限访问页面
                long destID = 0;
                if (uri.contains("LYDJ")) {
                    destID = 2;
                } else if (uri.contains("PICC")) {
                    destID = 3;
                } else if (uri.contains("YM")) {
                    destID = 1;
                }

                long finalDestID = destID;
                Long find = list.stream()  //实现查找，找到则返回匹配的对象，找不到则返回null
                        .filter(temp -> finalDestID == temp.longValue())
                        .findAny()
                        .orElse(null);
                if (find == null) throw new Exception();


            }

            //拦截器拿到用户信息后放入request中，以供Controller层获取
            request.setAttribute("ygdm", userData.get("ygdm").asString());
            request.setAttribute("ygxm", userData.get("ygxm").asString());
            request.setAttribute("ygzc", userData.get("ygzc").asString());
            request.setAttribute("ksmc", userData.get("ksmc").asString());


        } catch (Exception ex) {
            // 令牌解析错误（空、过期），重定向至登录页
            log.error("[token解析异常]" + ex.getMessage());

            // 如果是ViewController请求，直接重定向
            if (uri.contains("ViewController")) {
                response.sendRedirect("Login?TokenError");
                return;
            }
            // 如果是其他Conroller请求，说明是AJAX发起，以JSON格式返回错误信息
            else {
                response.setCharacterEncoding("UTF-8");
                response.setContentType("text/html;charset=utf-8");
                ReplyMsgDTO replyMsgDTO = new ReplyMsgDTO();
                replyMsgDTO.setStatus(false);
                replyMsgDTO.setDetail("令牌无效，请重新登录！");
                response.getWriter().write(new Gson().toJson(replyMsgDTO));
                return;
            }

        }
        chain.doFilter(req, res);


    }

    @Override
    public void destroy() {
    }
}
